import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @description:
 * @title: AbstractQueuedSynchronizerDemo
 * @author: zp
 * @date: 2021/8/21 21:03
 * 完整理解AQS 抽象队列同步器
 * ReentrantLock 可重入锁 默认非公平
 *  abstract static class Sync extends AbstractQueuedSynchronizer 使用同步器
 *  <p>
 *      tryAcquire 当都为true时 未抢占的线程 已经添加到阻塞队列中 等待循环取出 非公平模式
 *       if (!tryAcquire(arg) &&
 *             acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
 *             selfInterrupt();
 *  </p>
 *  <p>
 *      protected final boolean tryAcquire(int acquires) {
 *             final Thread current = Thread.currentThread();
 *             int c = getState();
 *             if (c == 0) {
 *             //判断阻塞队列中是否有元素 如果有取出等待时间最长的线程 其他的和非公平的一致
 *                 if (!hasQueuedPredecessors() &&
 *                     compareAndSetState(0, acquires)) {
 *                     setExclusiveOwnerThread(current);
 *                     return true;
 *                 }
 *             }
 *             else if (current == getExclusiveOwnerThread()) {
 *                 int nextc = c + acquires;
 *                 if (nextc < 0)
 *                     throw new Error("Maximum lock count exceeded");
 *                 setState(nextc);
 *                 return true;
 *             }
 *             return false;
 *         }
 *     }
 *  </p>
 *  <p>
 *
 *      先尝试修改 unsafe.compareAndSwapInt(this, stateOffset, expect, update); CAS
 *         if (compareAndSetState(0, 1))
 *             当交换成功 获取当先线程对象
 *             setExclusiveOwnerThread(Thread.currentThread());
 *         else
 *             如果不成功
 *             acquire(1);
 *  </p>
 *
 *  <p>
 *
 *      final boolean nonfairTryAcquire(int acquires) {
 *              //获取当前线程
 *             final Thread current = Thread.currentThread();
 *             //获取锁变量
 *             int c = getState();
 *             if (c == 0) {
 *                 //防止刚释放锁 就被抢占
 *                 if (compareAndSetState(0, acquires)) {
 *                     setExclusiveOwnerThread(current);
 *                     return true;
 *                 }
 *             }
 *             else if (current == getExclusiveOwnerThread()) {
 *                  //如果是同一个线程 抢占了同一把锁 把标志位加一 在释放的时候减一 这就是为什么 lock和unlock是成对出现 如果不写unlock 会出现线程阻塞的情况
 *                 int nextc = c + acquires;
 *                 if (nextc < 0) // overflow
 *                     throw new Error("Maximum lock count exceeded");
 *                 setState(nextc);
 *                 return true;
 *             }
 *             return false;
 *         }
 *  </p>
 *
 *  <p> addWaiter
 *      把当前线程添加到等待队列中
 *      Node node = new Node(Thread.currentThread(), mode);
 *         // Try the fast path of enq; backup to full enq on failure
 *         Node pred = tail;
 *         if (pred != null) {
 *             node.prev = pred;
 *             if (compareAndSetTail(pred, node)) {
 *                 pred.next = node;
 *                 return node;
 *             }
 *         }
 *         enq(node);
 *         return node;
 *  </p>
 *
 *  <p>selfInterrupt
 *      //获取线程是否是中断状态
 *      Thread.currentThread().interrupt();
 *  </p>
 *
 *  如果等待队列是没有元素的 会先创建一个没有任何线程的引用的空节点（哨兵节点）
 *  如果未释放锁 在阻塞队列中 使用LockSupport.park(); 挂起
 *  如果锁已经释放 LockSupport.unpark(); 释放线程
 */
public class AbstractQueuedSynchronizerDemo {
    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
    }
}
